package org.iamd.security;

import java.util.HashMap;
import java.util.Map;

import org.iamd.util.CommonMsgKeys;

/**
 * Мениджър на услугите на сигурността. Предлага различни типове услуги. Singleton pattern.
 * 
 * @author И. Атанасов
 */
public class SecurityServicesManager {

	/** Единствената инстанция на класа. */
	private static SecurityServicesManager instance;

	/**
	 * @return единствената инстанция на класа.
	 */
	public static SecurityServicesManager getInstance() {
		if (instance == null) {
			instance = new SecurityServicesManager();
		}
		return instance;
	}

	/** Map с услуги, които предлага модул Сигурност. */
	private Map<Class<?>, Object> serviceMap;

	/**
	 * Инициализация на map-a с услуги, както и на логера.
	 */
	private SecurityServicesManager() {
		this.serviceMap = new HashMap<Class<?>, Object>();
	}

	/**
	 * По подаден клас търси сервиз на сигурността и го връща като резултат. Хвърля
	 * {@link NullPointerException}, ако входния параметър е <code>null</code>.
	 * 
	 * @param <T>
	 *            тип сервиз
	 * @param clazz
	 *            клас на сервиз
	 * 
	 * @return намерения сервиз
	 * 
	 * @throws SecurityException
	 *             ако сервиза не е намерен
	 */
	public <T extends ISecurityService> T getService(Class<T> clazz) throws SecurityException {
		if (clazz == null) {
			throw new NullPointerException("Input class cannot be null");
		}
		Object result = this.serviceMap.get(clazz);
		if (result != null) {
			return clazz.cast(this.serviceMap.get(clazz));
		}
		throw new SecurityException(CommonMsgKeys.M0007_SEC_SERVICE_NOT_FOUND,
				new String[] { clazz.getName() });
	}

	/**
	 * Инициализация на мапа с услугите.
	 * 
	 * @param servicesMap
	 *            услуги с ключ клас и стойност самата услуга
	 */
	void init(Map<Class<? extends ISecurityService>, ISecurityService> servicesMap) {
		this.serviceMap.putAll(servicesMap);
	}

}